package com.siyoumi.app.modules.sms.service;

import com.siyoumi.app.entity.SysSms;
import com.siyoumi.app.entity.SysSmsSend;
import com.siyoumi.app.entity.SysStock;
import com.siyoumi.app.entity.SysUser;
import com.siyoumi.app.modules.sms.vo.VaSms;
import com.siyoumi.app.modules.sms.vo.VoSmsSend;
import com.siyoumi.app.modules.user.service.SvcSysUser;
import com.siyoumi.app.service.SysSmsSendService;
import com.siyoumi.app.service.SysSmsService;
import com.siyoumi.app.service.SysStockService;
import com.siyoumi.app.sys.service.ApiHandle;
import com.siyoumi.app.sys.service.api_handle.vo.VoApiSmsSend;
import com.siyoumi.component.XApp;
import com.siyoumi.component.XRedis;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

//短信
@Slf4j
@Service
public class SvcSms
        implements IWebService {
    static public SvcSms getBean() {
        return XSpringContext.getBean(SvcSms.class);
    }

    static public SysSmsService getApp() {
        return SysSmsService.getBean();
    }


    public SysSms getEntity(String id) {
        return XRedis.getBean().getAndSetData(getApp().getEntityCacheKey(id), k -> {
            return getApp().getEntity(id);
        }, SysSms.class, true);
    }

    public JoinWrapperPlus<SysSms> listQuery() {
        return listQuery(InputData.getIns());
    }

    /**
     * select
     *
     * @return query
     */
    public JoinWrapperPlus<SysSms> listQuery(InputData inputData) {
        String name = inputData.input("name");

        JoinWrapperPlus<SysSms> query = getApp().join();
        query.eq("sms_x_id", XHttpContext.getX());
        //排序
        query.orderByDesc("sms_create_date")
                .orderByAsc("sms_id");
        if (XStr.hasAnyText(name)) { //名称
            query.like("sms_name", name);
        }

        return query;
    }

    public JoinWrapperPlus<SysSmsSend> listSendQuery() {
        return listSendQuery(InputData.getIns());
    }

    public JoinWrapperPlus<SysSmsSend> listSendQuery(InputData inputData) {
        String smsId = inputData.input("sms_id");
        String uid = inputData.input("uid");
        String phone = inputData.input("phone");

        JoinWrapperPlus<SysSmsSend> query = SysSmsSendService.getBean().join();
        query.eq("ssend_x_id", XHttpContext.getX());
        //排序
        query.orderByDesc("ssend_create_date")
                .orderByAsc("ssend_id");
        if (XStr.hasAnyText(smsId)) { //短信ID
            query.eq("ssend_sms_id", smsId);
        }
        if (XStr.hasAnyText(uid)) { //uid
            query.eq("ssend_uid", uid);
        }
        if (XStr.hasAnyText(phone)) { //手机号
            query.eq("ssend_phone", phone);
        }
        return query;
    }

    public XReturn edit(InputData inputData, VaSms vo) {
        List<String> ignoreField = new ArrayList<>();
        if (inputData.isAdminEdit()) {
            ignoreField.add("sms_api_type");
        } else {
            vo.setSms_api_type(XHttpContext.getXConfig().getAconfig_api_type());
        }

        return XApp.getTransaction().execute(status -> {
            XReturn r = getApp().saveEntity(inputData, vo, true, ignoreField);
            XValidator.err(r);

            SysSms entity = r.getData("entity");

            //库存
            SysStock entityStock = SysStockService.getBean().getEntityBySrc(entity.getKey(), false);
            if (entityStock == null) {
                entityStock = new SysStock();
                entityStock.setStock_x_id(XHttpContext.getX());
                entityStock.setStock_id_src(entity.getKey());
                entityStock.setStock_count_left(0L);

                SysStockService.getBean().save(entityStock);
            }
            if (vo.getSet_left() == 1) {
                SysStockService.getBean().updateLeft(entity.getKey(), vo.getLeft_count(), vo.getLeft_count_old());
            }

            getApp().delEntityCache(entity.getKey());
            return r;
        });
    }

    /**
     * 删除
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn delete(List<String> ids) {
        XReturn r = XReturn.getR(0);

        getApp().delete(ids);


        return r;
    }


    public XReturn sendCan(VoSmsSend vo) {
        SysSms entitySms = getEntity(vo.getSms_id());
        XValidator.isNull(entitySms, "sms_id error");

        SysStock entityStock = SysStockService.getBean().getEntityBySrc(entitySms.getKey(), false);
        if (entityStock.getStock_count_left() < 1) {
            return XReturn.getR(200134, "发送限度已用完");
        }

        SysUser entityUser = SvcSysUser.getBean().getEntity(vo.getUid());
        SvcSysUser.getBean().valid(entityUser);

        //判断用户发送频率redis

        return EnumSys.OK.getR();
    }

    /**
     * 发短信
     *
     * @param vo
     */
    public XReturn send(VoSmsSend vo) {
        XReturn r = sendCan(vo);
        if (r.err()) {
            return r;
        }

        //开始发短信
        return XApp.getTransaction().execute(status -> {
            SysUser entityUser = SvcSysUser.getBean().getEntity(vo.getUid());
            SysSms entitySms = getEntity(vo.getSms_id());
            //扣库存
            SysStockService.getBean().subStock(entitySms.getKey(), 1L);
            //
            SysSmsSend entitySend = new SysSmsSend();
            entitySend.setSsend_x_id(XHttpContext.getX());
            entitySend.setSsend_sms_id(vo.getSms_id());
            entitySend.setSsend_uid(vo.getUid());
            entitySend.setSsend_phone(entityUser.getUser_phone());
            entitySend.setAutoID();

            if (XStr.hasAnyText(entitySms.getSms_template_json())) { //短信模板占位符
                String tempJson = XStr.replaceByMap(entitySms.getSms_template_json(), vo.getReplaceArr());
                entitySend.setSsend_template_json(tempJson);
            }
            SysSmsSendService.getBean().save(entitySend);

            XReturn rr = XReturn.getR(0);
            rr.setData("entity", entitySend);

            return rr;
        });
    }

    /**
     * 发送短信API
     *
     * @param id
     */
    public XReturn sendApi(String id) {
        XValidator.isNullOrEmpty(id, "miss id");
        SysSmsSend entitySend = SysSmsSendService.getBean().getEntity(id);
        XValidator.isNull(entitySend, "id error");

        if (entitySend.getSsend_status() != 0) {
            return XReturn.getR(20193, "已处理");
        }

        SysSms entitySms = getApp().getEntity(entitySend.getSsend_sms_id());
        ApiHandle api = ApiHandle.of(entitySms.getSms_api_type());
        //
        VoApiSmsSend apiData = new VoApiSmsSend();
        apiData.setPhone(entitySend.getSsend_phone());
        apiData.setSign_name(entitySms.getSms_sign_name());
        apiData.setTemplate_code(entitySms.getSms_template_code());
        apiData.setTemplate_json(entitySend.getSsend_template_json());
        XReturn r = api.smsSend(apiData);

        //标记已发送
        SysSmsSend entityUpdate = new SysSmsSend();
        entityUpdate.setSsend_id(entitySend.getKey());
        entityUpdate.setSsend_status(10);
        if (r.ok()) {
            entityUpdate.setSsend_status(1);
        }
        entityUpdate.setSsend_status_date(XDate.now());
        entityUpdate.setSsend_errmsg(r.getErrMsg());
        SysSmsSendService.getBean().saveOrUpdatePassEqualField(entitySend, entityUpdate);

        return r;
    }
}
